// 单行文本输入框
import { input } from './input.js';
// 多行文本输入框
import { textarea } from './textarea.js';
// 下拉菜单
import { select } from './select.js';
// 单选框
import { radio } from './radio.js';
// 多选框
import { checkBox } from './checkbox.js';
// 日期选择器控件
import { inputDate } from './inputDate.js';
// 验证组件
import { verify } from './verify.js';
// 密码输入框
import { password } from './password.js';

var FormElement = {
    input: input,
    textarea: textarea,
    select: select,
    radio: radio,
    checkBox: checkBox,
    inputDate: inputDate,
    password: password
};


var formBox = function (options, parent) {
    this.options = {
        lable: '',
        annotate: '',
        stutas: 'show',
        size: 'middle',
        layoutName: 'name',
        className: '',
    };
    this.options = $.extend({}, this.options, options);
    this.parent = parent;
    var _lable = $('<div class="form_lable">' + this.options.lable + '</div>');
    this._Box = $('<div class="form_item_layout"></div>');
    this._error = $('<span class="form_error" style="display:none"></span>');
    this._annotate = $('<div class="form_annotate">' + this.options.annotate + '</div>')
    this.html = $('<div class="form_Item_box ' + this.options.className + ' ' + this.options.size + '"></div>');
    this.html.append(_lable);
    this.html.append(this._Box);
    this.html.append(this._error);
    this.html.append('<div style="clear:both"></div>')
    this.html.append(this._annotate);

    if (this.options.stutas != 'show') {
        this.hide();
    };
};
formBox.prototype = {
    varructor: this,
    render: function () {
        return this.html;
    },
    append: function (data) {
        this._Box.append(data);
    },
    showError: function (data) {
        this._error.text(data);
        this._error.css('display', 'block');
        this.html.addClass('form_error_type');
    },
    hideError: function () {
        this._error.css('display', 'none').text('');
        this.html.removeClass('form_error_type');
    },
    show: function () {
        this.options.stutas = 'show';
        this.html.css('display', 'block');
    },
    hide: function () {
        this.options.stutas = 'hide';
        this.html.css('display', 'none');
    }
};


var form = function (options) {
    this.options = $.extend({}, {
        type: 'all', // onlyChange / all / mergeByChange / mergeByOldData
        beforSet: function (data) {
            return data;
        },
        beforGet: function (data) {
            return data;
        },
    }, options);

    if (this.options.type != 'all' && this.options.type != 'onlyChange' && this.options.type != 'mergeByOldData' && this.options.type != 'mergeByOldDataChange') {
        console.error('表单赋值取值类型错误');
    };

    this.html = $('<div class="form_box"></div>');
    this.items = {};
    this.order = [];
    this.oldData = {};
    this.errorMessage = null;
    this.event = {
        beforGet: this.options.beforGet,
        beforSet: this.options.beforSet
    };
};

form.prototype = {
    varructor: this,
    setData: function (data) {
        this.event.beforSet.call(this, [data]);
        if (this.options.type == 'onlyChange') {
            this.oldData = {};
            for (var key in data) {
                if (this.items.hasOwnProperty(key) && data.hasOwnProperty(key)) {
                    this.items[key].set(data[key], true);
                    this.oldData[key] = data[key];
                }
            };
        } else if (this.options.type == 'mergeByOldDataChange') {
            this.oldData = data;
            for (var key in data) {
                if (this.items.hasOwnProperty(key) && data.hasOwnProperty(key)) {
                    this.items[key].set(data[key], true);
                }
            };
        };
    },
    setOptions: function (options) {
        this.html.empty();
        this.items = {};
        this.order = [];
        for (var i = 0; i < options.length; i++) {
            var itemOption = options[i];
            this.pushItem(itemOption);
        };
    },
    get: function () {
        var data = {};
        var isComplete = true;
        var stutas = false;
        for (var key in this.items) {
            if (this.items.hasOwnProperty(key)) {
                var element = this.items[key];
                element.get(function (error, result) {
                    if (!error) {
                        data[key] = result;
                    } else {
                        if (!stutas) {
                            stutas = error;
                        };
                        isComplete = false;
                    };
                });
            };
            if (!isComplete) {
                break;
            };
        };
        var _isCompleteData = null;

        if (isComplete) {
            this.errorMessage = null;
            if (this.options.type == 'all') {
                _isCompleteData = data;
            } else if (this.options.type == 'mergeByOldData') {
                _isCompleteData = $.extend({}, this.oldData, data);
            } else if (this.options.type == 'onlyChange') {
                _isCompleteData = this.mergeData(data, this.oldData);
            } else if (this.options.type == 'mergeByOldDataChange') {
                _isCompleteData = this.mergeData(data, this.oldData);
            };
            this.event.beforGet.call(this, _isCompleteData);
            return _isCompleteData;
        } else {
            this.errorMessage = stutas;
            return false;
        };
    },
    mergeData: function (data, oldData) {
        var returnData = $.extend({}, oldData);
        var _length = 0;
        for (var key in data) {
            if (data.hasOwnProperty(key)) {
                _length++;
                var formDataItem = data[key];
                if (verify.is('object', formDataItem)) {
                    var addKeyArray = [];
                    for (var checkBoxKey in formDataItem) {
                        if (formDataItem.hasOwnProperty(checkBoxKey)) {
                            var element = formDataItem[checkBoxKey];
                            if (element != returnData[key][checkBoxKey]) {
                                addKeyArray.push(checkBoxKey);
                            };
                        };
                    };
                    if (addKeyArray.length == 0) {
                        _length--;
                        delete returnData[key]
                    } else {
                        returnData[key] = {};
                        for (var i = 0; i < addKeyArray.length; i++) {
                            var element = addKeyArray[i];
                            returnData[key][element] = formDataItem[element];
                        }
                    };
                } else {
                    if (formDataItem == returnData[key]) {
                        _length--;
                        delete returnData[key];
                    } else {
                        returnData[key] = formDataItem;
                    };
                };
            }
        };
        if (_length == 0) {
            this.errorMessage = '未对表单进行任何修改';
            return false;
        } else {
            this.errorMessage = null;
            return returnData;
        };
    },
    hasKey: function (key) {
        if (this.items.hasOwnProperty(key)) {
            var element = this.items[key];
            return element;
        } else {
            return false;
        }
    },
    pushItem: function (option) {
        this.items[option.key] = new FormElement[option.type](option.element, new formBox(option.box));
        this.html.append(this.items[option.key].layout.render());
        this.order.push(option.key);
    },
    addItem: function (option, index) {
        this.items[option.key] = new FormElement[option.type](option.element, new formBox(option.box));
        this.html.find('.form_Item_box').eq(index).after(this.items[option.key].layout.render());
        this.order.splice(index, 0, option.key);
    },
    removeItem: function (key) {
        var obj = this.hasKey(key);
        if (obj) {
            this.items[key].layout.html.remove();
            delete this.items[key];
            var index = $.inArray(key, this.order);
            if (index != -1) {
                this.order.splice(index, 1);
            };
            if (this.options.type == 'onlyChange') {
                if (this.oldData.hasOwnProperty(key)) {
                    delete this.oldData[key];
                };
            }
        };
    },
    beforGet: function (event) {
        this.options.beforGet = event;
    },
    getFormObject: function (type, options) {
        if (FormElement.hasOwnProperty(type)) {
            var element = new FormElement[type](options);
            return element;
        } else {
            console.error('form => 不存在的表单类型');
            return false;
        }
    }
};

export { form };












